Github上のASLファイルの変更をトリガーにしてStepFunctionsを自動デプロイする(Github Actions + AWS CDK)
「ASLファイルの変更をトリガーにStepFunctionsを自動デプロイしたい」
GitHub等ででASLファイルを管理している環境で、ASLファイルの変更があった際に自動でStepFunctionの設定も更新できるようにしたいことがありました。
今回は以下の構成でやってみました。
- IaCツール: AWS CDK
- CI/CDツール: Github Actions
IaCツールやCI/CDツールが異なる場合も、基本的には同じような流れで実行できるかと思います。 (例えば、IaCツールがTerraformだったらcdk deployの部分をterraform applyに変える等。)
概要
- AWS CDKでStep Functionsを作成
- ASLファイルの変更をトリガーにGithub Actionsを実行
- Github Acitions上でAWS CDKを使用して環境を更新(cdk deploy)
StepFunctionsはIaCツール(AWS CDK)で作成します。
IaCツールでStepFunctionsを作成するメリットとしては、複数のステートマシンを作成したい場合もCI/CDパイプラインを組むのが容易だからです。
ASLファイルの変更をトリガーにCI/CDツール上で、「aws stepfunctions update-state-machine」コマンドを実行してステートマシンを更新することも可能かと思います。
しかし、ワークフローの数が増えていくとその分コマンドを増やす・または何かしらのスクリプト作成の必要があります。
aws stepfunctions update-state-machine --state-machine-arn <state-machine AのARN> --definition <state-machin A definition> aws stepfunctions update-state-machine --state-machine-arn <state-machine BのARN> --definition <state-machin B definition> aws stepfunctions update-state-machine --state-machine-arn <state-machine CのARN> --definition <state-machin C definition> # 数が増えると追加が必要
IaCツールで作成する場合は、ステートマシンが増えてもコマンドを変更する必要はありません。 (IaCツール内で作成するステートマシンの記述は必要です)
npm ci npm run cdk deploy "*" --require-approval never
やってみた
コードは以下にあります。
msato0731/cdk-stepfunctions-asl
AWS CDKで環境を用意する
CDKのコードでは既存のASLファイルを使うため、今回はL1 Constructを使用しています。 Github Actionsで使うIAMロールも同じスタックで作成しています。
import * as cdk from 'aws-cdk-lib' import * as iam from 'aws-cdk-lib/aws-iam' import * as stepfunctions from 'aws-cdk-lib/aws-stepfunctions' import { GithubActionsIdentityProvider, GithubActionsRole } from 'aws-cdk-github-oidc'; import * as fs from 'fs' import { Construct } from 'constructs' export class StepfunctionsStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props) // すでにProvider作成済みのため const provider = GithubActionsIdentityProvider.fromAccount(this, this.account) // Provider存在しない場合は、以下の記述が必要 // const provider = new GithubActionsIdentityProvider(this, 'GithubProvider'); const githubActionsRole = new GithubActionsRole(this, 'GithubActionsRole', { provider: provider, owner: 'msato0731', // 書き換え必要 repo: 'cdk-stepfunctions-asl', roleName: 'stepfunctions-gh-deploy-test', maxSessionDuration: cdk.Duration.hours(2), }); // デプロイ検証用のため強めの権限付与 githubActionsRole.addManagedPolicy( iam.ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess") ) new cdk.CfnOutput(this, "GithubActionsRoleArn", { value: githubActionsRole.roleArn }) // ステートマシン作成にIAM Role必須のため、今回の検証ではポリシーは不要 const stepFunctionsRole = new iam.Role(this, "StepFunctionsRole", { assumedBy: new iam.ServicePrincipal('states.amazonaws.com') }) // ステートマシン作成 const file = fs.readFileSync('./step-functions/HelloWorld.asl.json') new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine', { definitionString: file.toString(), stateMachineName: 'HelloWorld-CDK', roleArn: stepFunctionsRole.roleArn }) } }
補足: ステートマシン追加
「CfnStateMachine」を以下のように追加することで、ステートマシンを追加できます。
// 省略 const file = fs.readFileSync('./step-functions/HelloWorld.asl.json') new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine', { definitionString: file.toString(), stateMachineName: 'HelloWorld-CDK', roleArn: stepFunctionsRole.roleArn }) // ステートマシン追加 const file2 = fs.readFileSync('./step-functions/HelloWorld2.asl.json') new stepfunctions.CfnStateMachine(this, 'HelloWorldStateMachine2', { definitionString: file.toString(), stateMachineName: 'HelloWorld-CDK2', roleArn: stepFunctionsRole.roleArn })
Github ActionsのシークレットにIAMロールをセット
「cdk deploy」を実行して作成されたCloudFormationスタックの出力を確認します。 IAMロールARNが出力されるため、これをコピーしておきます。
GithubActionsのシークレットに以下を追加します。
- シークレット名: AWS_IAM_ROLE_ARN
- 値: [コピーしたIAMロールARN]
Github Actionsのワークフローファイルを用意
CDKデプロイ用のワークフローファイルを用意します。
mainブランチにPR時に、cdk diffを実施します。 mainブランチでpushしたタイミング(PR マージ)時に、cdk deployが実行されます。
name: deploy-cdk on: pull_request: branches: - main push: branches: - main jobs: deploy-cdk: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - uses: actions/checkout@v2 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }} aws-region: ap-northeast-1 - name: Setup Node uses: actions/setup-node@v1 with: node-version: '16' - name: CDK package install run: npm ci - name: CDK Diff Check if: contains(github.event_name, 'pull_request') run: | npm run cdk -- diff "*" - name: CDK Deploy if: contains(github.event_name, 'push') run: | npm run cdk -- deploy --require-approval never "*"
動作確認
修正前は、以下の状態です。
ASLファイルを修正して、PRを作成します。 「StepFunctions」という名前で、Pass Stateを追加しました。
PR時にはGithub Actionsによってcdk diffが実行されるため変更差分を確認します。
変更差分が問題なければ、マージします。 Github Actionsによって、「cdk deploy」が自動で実行されます。
マネジメントコンソール上からも、変更が適用されたことが確認できました
おわりに
CIツールにGithub Actions・IaCツールにAWS CDKを使用して、ASLファイルの変更があった際にステートマシンに変更を自動反映させる方法でした。
誰かの参考になれば幸いです。
以上、AWS事業本部の佐藤(@chari7311)でした。